from abc import abstractmethod
from threading import Thread
from DrissionPage.tools import Listener

from common.web.Base import Chrome, Action
from config.Setting import Setting


class Login(Chrome):
    def __init__(self, account, password):
        super().__init__()
        self.account = account
        self.password = password
        self.hand = Action(self.page)
        self.action_map = {}
        self.login_state = False
        self.tid = None
        self.slider_tries = 0
        self.listener = Listener(self.port)

    def action(self):
        self.action_map = self.listen_init()
        task_listen = Thread(target=self.listen)
        task_1 = Thread(target=self.login)
        task_listen.start()
        task_1.start()
        task_listen.join()
        task_1.join()
        if self.login_state:
            return self.page
        else:
            raise Exception

    def listen(self):
        self.listener.show_msg = False
        listener = self.listener
        action_map = self.action_map
        listener.set_targets([_ for _ in action_map])
        listener.listen()
        for i in listener.steps():
            url = i.url
            response = i.body
            Thread(target=action_map[url], args=(response,)).start()

    @abstractmethod
    def listen_init(self): ...

    def stop(self, errMsg=None):
        self.listener.stop()
        if errMsg:
            raise ThrowError(errMsg)

    @abstractmethod
    def login(self): ...

    @abstractmethod
    def login_step(self): ...

    @abstractmethod
    def logout_step(self): ...

    @abstractmethod
    def phone_code(self): ...

    @abstractmethod
    def phone_code_step(self): ...

    @abstractmethod
    def slider(self): ...

    def slider_check(self, response=None):
        if self.slider_tries >= 5:
            self.stop('滑块验证尝试过多')
        else:
            self.slider_tries += 1
            self.slider()


class Login_new(Chrome):
    def __init__(self, account, password, **kwargs):
        port = kwargs.get('port') or Setting.CHROME_PORT
        super().__init__(port)
        self.account = account
        self.password = password
        self.email = kwargs.get('email')
        self.hand = Action(self.page)
        self.port = port
        self.login_state = False
        self.tid = None
        self.slider_tries = 5


class ThrowError(Exception):
    def __init__(self, message):
        super().__init__(message)

